def multisuper(basecls, obj, name, *args, **kwargs):
    """Calls a super method if not already called with the given *args and **kwargs.

    Return values not supported in this implementation (use for, e.g., __init__).

    Usage:
    class C(A, B):
        def __init__(self):
            # calls A.__init__(self, 'x') if C < A in self.__class__.mro()
            multisuper(A, self, '__init__', 'x')
    """
    cls = obj.__class__
    ok = False
    for base in cls.mro():
        if base is cls:
            ok = True  # need to see cls before basecls
        elif base is basecls:
            if ok:
                method = getattr(base, name)
                method(*args, **kwargs)
            return

class O(object):
    def fn(self, a):
        print a

class A(O):
    def fn(self):
        if has_precedence(self, A, O): O.fn(self, "a")
        print "in A"

class C(A, O):
    def fn(self):
        if has_precedence(self, C, O): O.fn(self, "c")
        A.fn(self)
        print "in C"

c = C()
c.fn()

#class D(C, A):
 #   def fn():
  #      super(A, self, 'fn', 'D calling A', 'second arg')
   #     super(C, self, 'fn', 'D calling C')

#d = D()
#d#.fn()


#class T:
    #pass
#t = T()
#tp = Proxy(t)
#print hasattr(t, '__add__')
#print hasattr(tp, '__add__')

#import ahh.util as util
#t = util.Proxy(5)
#y = util.Proxy(2.0)

#print t
#print t+1
#print 1+t
#print t+2.0
#print 2.0+t
#print t+y

#import ahh.util as util
#g = util.CodeGenerator()

#unary_ops = {
    #'__neg__': '-',
    #'__pos__': '+',
    #'__invert__': '~'
#}
#for name, op in unary_ops.iteritems():
    #g.line("""def %s(self):
              #\   return %sself._wrapped""" % (name, op), 2)

#left_binary_ops = {
    #'__lt__': '<',
    #'__le__': '<=',
    #'__eq__': '==',
    #'__add__': '+',
    #'__sub__': '-',
    #'__mul__': '*',
    #'__floordiv__': '//',
    #'__mod__': '%',
    #'__lshift__': '<<',
    #'__rshift__': '>>',
    #'__and__': '&',
    #'__or__': '|',
    #'__xor__': '^',
    #'__div__': '/',
    #'__truediv__': '/'
#}
#for name, op in left_binary_ops.iteritems():
    #g.line("""def %s(self, other):
              #\   return self._wrapped %s other""" % (name, op), 2)

#right_binary_ops = {
    #'__radd__': '+',
    #'__rsub__': '-',
    #'__rmul__': '*',
    #'__rdiv__': '/',
    #'__rtruediv__': '/',
    #'__rfloordiv__': '//',
    #'__rmod__': '%',
    #'__rlshift__': '<<',
    #'__rrshift__': '>>',
    #'__rand__': '&',
    #'__rxor__': '^',
    #'__ror__': '|',
    #'__contains__': 'in'
#}
#for name, op in right_binary_ops.iteritems():
    #g.line("""def %s(self, other):
              #\   return other %s self._wrapped""" % (name, op), 2)

#in_place_binary_ops = {
    #'__iadd__': '+',
    #'__isub__': '-',
    #'__imul__': '*',
    #'__idiv__': '/',
    #'__itruediv__': '/',
    #'__ifloordiv__': '//',
    #'__imod__': '%',
    #'__ipow__': '**',  # TODO: is there some way to send modulo in with the operator version?
    #'__ilshift__': '<<',
    #'__irshift__': '>>',
    #'__iand__': '&',
    #'__ixor__': '^',
    #'__ior__': '|'
#}
#for name, op in in_place_binary_ops.iteritems():
    #g.line("""def %s(self, other):
              #\   self._wrapped %s= other""" % (name, op), 2)

#fn_ops = {
    #'__nonzero__': 'bool',
    #'__str__': 'str',
    #'__repr__': 'repr',
    #'__unicode__': 'unicode',
    #'__len__': 'len',
    #'__reversed__': 'reversed',
    #'__divmod__': 'divmod',
    #'__pow__': 'pow',
    #'__abs__': 'abs',
    #'__complex__': 'complex',
    #'__int__': 'int',
    #'__long__': 'long',
    #'__float__': 'float',
    #'__oct__': 'oct',
    #'__hex__': 'hex',
    #'__getattr__': 'getattr',
    #'__setattr__': 'setattr',
    #'__delattr__': 'delattr'
#}
#for name, op in fn_ops.iteritems():
    #g.line("""def %s(self, *args, **kwargs):
              #\   return %s(self._wrapped, *args, **kwargs)""" % (name, op), 2)

#right_binary_fn_ops = {
    #'rdivmod': 'divmod',
    #'rpow': 'pow'
#}
#for name, op in right_binary_fn_ops.iteritems():
    #g.line("""def %s(self, other, *args, **kwargs):
              #\   return %s(other, self._wrapped, *args, **kwargs)""" %
           #(name, op), 2)

#method_ops = ( '__hash__', '__iter__', '__index__', '_coerce__' )
#for op in method_ops:
    #g.line("""def %s(self, *args, **kwargs):
              #\   return self._wrapped.%s(*args, **kwargs)""" % (op, op), 2)

#g.line("""def __call__(self, name, *args, **kwargs):
          #\   try:
          #\       return getattr(self._wrapped, name)(*args, **kwargs)
          #\   except AttributeError:
          #\       return self._wrapped.__call__(name, *args, **kwargs)

          #def __getitem__(self, name):
          #\   return self._wrapped[name]

          #def __setitem__(self, name, value):
          #\   self._wrapped[name] = value

          #def __delitem__(self, name):
          #\   del self._wrapped[name]

          #def __del__(self):
          #\   if hasattr(self._wrapped, '__del__'):
          #\       self._wrapped.__del__()""")

#print g.code


#import ahh.util as util
#Proxy = util.Proxy()
#class T(Proxy):
    #def __init__(self, x):
        #Proxy.__init__(self, x)

#t = T(5)
#print t
##print 5 + t
##print 2 * t
#y = T(2.0)
#print y*t


#def define_property(obj, name, fget=None, fset=None, fdel=None, doc=None):
    #exec ("""class %(classname)s(obj.__class__):
    #__doc__ = obj.__class__.__doc__
    #%(name)s = property(fget, fset, fdel, doc)
#obj.__class__ = %(classname)s""" % { 'classname': obj.__class__.__name__,
                                     #'name': name}) \
         #in locals()


#class T(object):
    #"""Test"""
    #def __init__(self):
        #self.x = 5

#t = T()
#define_property(t, 'test', lambda self: "test")
#print t.test


#import ahh.util as util

#class Z(object):
    #def __setattr__(self, name, value):
        #if name == 'i':
            #object.__setattr__(self, 'i', "I")
        #else:
            #object.__setattr__(self, name, value)
        ##else:
            ##raise AttributeError()

#class B(Z):
    #@property
    #def b(self):
        #return "B"

#class D(object):
    #def __getattribute__(self, name):
        #if name == "d":
            #return "D"
        #else:
            #raise AttributeError()
    #pass

#class A(B, D):
    #def __init__(self):
        #self.e = "E"

    #def __getattribute__(self, name):
        #if name == "a":
            #return "A"
        #else:
            #self_type = type(self)
            #for base in self_type.mro():
                #if base is self_type:
                    #continue
                #else:
                    #try:
                        #return base.__getattribute__(self, name)
                    #except AttributeError:
                        #continue
        #raise AttributeError()

    #def __setattr__(self, name, value):
        #if name =='g':
            #object.__setattr__(self, 'g', "G")
        #else:
            #my_type = type(self)
            #for base in my_type.mro():
                #if base is my_type:
                    #continue
                #else:
                    #try:
                        #sa = base.__setattr__
                    #except AttributeError:
                        #continue
                    #if sa != object.__setattr__:
                        #sa(self, name, value)
                        #return
            #object.__setattr__(self, name, value)

    #def __getattr__(self, name):
        #if name == 'f':
            #return 'F'

    #@property
    #def c(self):
        #return "C"

#a = A()
#print a.a
#print a.b
#print a.c
#print a.d
#print a.e
#print a.f
#a.g = 5
#print a.g
#a.h = "H"
#print a.h
#a.i = 5
#print a.i


#x = { 'hello': 'hi' }
#Wrapped = util.Wrapped()
#class Test(Wrapped):
    #def __init__(self, x):
        #Wrapped.__init__(self, x)

    #def test(self):
        #print "test"

    #@property
    #def p(self):
        #return 'p'

#t = Test(5)
#t.test()
#print t + 1

#for name, val in t.iteritems():
    #print name + ":", val

# The following script was used to generate the body of this class
# The following script was used to generate the body of this class
#import ahh.util as util
#g = util.CodeGenerator()

#ops = ('__del__', '__hash__', '__nonzero__',
       #'__unicode__', '__repr__', '__str__',
       #'__len__', '__iter__', '__reversed__',
       #'__neg__', '__pos__', '__abs__', '__invert__',
       #'__complex__', '__int__', '__long__', '__float__',
       #'__oct__', '__hex__',
       #'__index__', '__enter__', '__exit__',
       #'__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__',
       #'__cmp__',
       #'__getattr__', '__setattr__', '__delattr__',
       #'__getitem__', '__setitem__', '__delitem__',
       #'__contains__',
       #'__add__', '__sub__', '__mul__', '__floordiv__', '__mod__',
       #'__pow__', '__div__', '__truediv__'
       #'__radd__', '__rsub__', '__rmul__', '__rfloordiv__', '__rmod__',
       #'__rpow__', '__rdiv__', '__rtruediv__',
       #'__lshift__', '__rshift__', '__and__', '__xor__', '__or__',
       #'__rlshift__', '__rrshift__', '__rand__', '__rxor__', '__ror___',
       #'__call__')
#for op in ops:
    #g.line("""if "%(op)s" not in disabled:
    #\   def %(op)s(self, *args, **kwargs):
    #\       try:
    #\           return self._wrapped.%(op)s(*args, **kwargs)
    #\       except (TypeError, AttributeError):
    #\           return NotImplemented
    #""" % { 'op': op })

#in_place = { '__iadd__': '+',
             #'__isub__': '-',
             #'__imul__': '*',
             #'__ifloordiv__': '//',
             #'__imod__': '%',
             #'__ipow__': '**',
             #'__idiv__': '/',
             #'__itruediv__': '/',

             #'__ilshift__': '<<',
             #'__irshift__': '>>',
             #'__iand__': '&',
             #'__ior__': '|',
           #}
#for op, single in in_place.iteritems():
    #g.line("""if "%(op)s" not in disabled:
    #\   def %(op)s(self, other):
    #\       try:
    #\           return self._wrapped.%(op)s(other)
    #\       except (TypeError, AttributeError):
    #\           try:
    #\               self._wrapped = self._wrapped %(single)s other
    #\           except (TypeError, AttributeError):
    #\               return NotImplemented
    #""" % { 'op': op, 'single': single })

#print g.code

#import numpy
#import random
#import time
#from ahh.util.np import JaggedMatrix

#counts = [3200, 800]
#P = numpy.array([ [0.15, 0.4],
                  #[0.4, 0.4] ])

#start_time = time.time()
#d = len(counts)
#N = sum(counts)
#ranges = [ ]
#prev_end = 0
#for count in counts:
    #new_end = prev_end + count
    #ranges.append((prev_end, new_end))
    #prev_end = new_end

#neighbor_count = numpy.empty((N, d), numpy.int32)

#for target in xrange(d):
    #for src, ((start, end), count) in enumerate(zip(ranges, counts)):
        #neighbor_count[start:end, target] = numpy.random.binomial(
            #counts[target], P[target, src], count)

#total_neighbor_count = numpy.sum(neighbor_count, 1)
#cm = JaggedMatrix.presized(total_neighbor_count)

#for i in xrange(N):
    #prev_count_end = 0
    #for target in xrange(d):
        #target_start, target_end = ranges[target]
        #n = neighbor_count[i, target]
        #new_count_end = prev_count_end + n
        #cm[i][prev_count_end:new_count_end] = random.sample(
            #xrange(counts[target]), n)
        #cm[i][prev_count_end:new_count_end] += target_start
        #prev_count_end = new_count_end

#elapsed = time.time() - start_time
#print elapsed

#def ConnectRandomly(cm, src_range, target_range, p):

    #(src_start, src_end) = src_range
    #(target_start, target_end) = target_range

    #src_num = src_end - src_start
    #target_num = target_end - target_start

    #num_targets = numpy.random.binomial(target_num, p, src_num)

    #for i in xrange(src_num):
        #sample = random.sample(xrange(target_start, target_end), num_targets[i])
        #cm[src_start + i].extend(sample)

#start_time = time.time()
#cm = [ [] for i in xrange(4000) ]
#ConnectRandomly(cm, (0, 3200), (0, 3200), 0.15)
#ConnectRandomly(cm, (0, 3200), (3200, 4000), 0.4)
#ConnectRandomly(cm, (3200, 4000), (0, 3200), 0.4)
#ConnectRandomly(cm, (3200, 4000), (3200, 4000), 0.4)
#cm = [ numpy.array(arr, numpy.int32) for arr in cm ]
#elapsed = time.time() - start_time
#print elapsed
